package cn.hackcloud.concurrency.readwritelock;

/**
 * 读锁实现
 * Created by www.ibfbc.com
 */
public class ReadLock implements Lock {
    final ReadWriteLockImpl readWriteLock;

    public ReadLock(ReadWriteLockImpl readWriteLock) {
        this.readWriteLock = readWriteLock;
    }

    @Override
    public void lock() throws InterruptedException {
        //使用MUTEX作为锁
        synchronized (readWriteLock.getMutex()) {
            //若此时有线程正在进行写操作，获取有写线程正在等待
            // 并且偏向锁标识为true时，就会无法获得锁，只能被挂起
            while (readWriteLock.getWritingWriters() > 0 || (readWriteLock.gerPreferWriter()
                    && readWriteLock.getWaitingWriters() > 0)) {
                readWriteLock.getMutex().wait();
            }
            //成功获得读锁，并且是readingReader的数量增加
            readWriteLock.incrementReadingReaders();

        }
    }

    @Override
    public void unlock() {
        //使用MUTEX作为锁
        synchronized (readWriteLock.getMutex()) {
            //释放锁的过程就是使当前reading的数量-1
            readWriteLock.decrementReadingReaders();
            //将referWriter设置为true可以使writer线程获得更多的机会
            readWriteLock.changePreferWriter(true);
            //通知唤醒Mutex关联monitor wait set的中的线程
            readWriteLock.getMutex().notifyAll();

        }
    }
}
